The approval sheet redrawn against the real V1 protocol. Consequence summary, the Effects row and the Recommended block are gone — the daemon does not send them, so the client cannot show them. The sheet now leads with the request title and tool, renders the literal payload, and treats permission duration as a decision rather than as a stated fact. Sessions and Chat are untouched; this file supersedes only the approval portions of A Master Core v1 and A Master Proofs v1.
All five frames use this presentation, not the generic PocketSheet. Nothing about it is decorative: every part of the contract exists to stop a security decision resolving without the user.
Header and decision bar are pinned; only the body scrolls. A long command, an expanded diff or 200% type grows the body alone, so the actions cannot leave the screen.
System back keeps the sheet open and returns nothing to the daemon. Scrim taps are consumed. There is no grabber and the drag gesture is disabled, so the sheet cannot be flung away mid-decision.
An explicit decision resolves the request and closes the sheet. AskWithdrawn(TIMED_OUT) turns it into TimeoutTerminal, which the user may then dismiss. An ordinary withdrawal or a session close removes the sheet immediately and advances the queue. System back, scrim taps and swipe resolve nothing at any point, and the client never resolves a request on its own clock.
Only the timed-out withdrawal produces it. Decisions are replaced by the daemon's outcome and a single Dismiss, and this is the one state in which the sheet may be dismissed. Other withdrawals leave nothing behind to dismiss.
The first three are not in the V1 payload. The fourth was a fact about a decision the user had not made yet; scope now lives in the action labels.
Stage C is the only exclusive choice; stage D composes on top of whatever C produced. Availability is derived only from capability flags — an action the daemon did not offer is not rendered, never rendered disabled, and no cell is reserved for it. Two offered grants fill a 2×2 grid; one offered grant produces a 2 + 1 grid at the same tile size.
Owns the presentation contract: no grabber, no drag, swallowed scrim, intercepted back, three pinned-scroll-pinned zones and safe-area insets. Never the generic PocketSheet.
State mark and label, optional queue counter, and either the countdown with its fail-closed sentence or the waiting state. Pinned.
One of command, diff or plan, chosen by which field arrived. Mono, verbatim, character wrapping. No summarising layer above it.
Badge, optional reason, optional codes and assessedAt. Subscribes to PermissionRiskUpdated and can appear after the sheet opens; it never reserves space before it does.
Hairline row carrying workdir from session context. Omitted when the session has none.
Grid built from grantOptions plus Deny and Retry safer. Owns emphasis: widest offered grant on ordinary, Allow once when danger is set. Hosts the More options row when session scope exists.
The current client gates V2 on grantOptions containing task. This handoff changes the gate to grantOptions != null, so a grant-aware peer offering only once no longer falls back to legacy and no longer offers an Always allow the peer never authorised. Rendered actions must match the offered flags exactly.
Deny, Allow once, Always allow. Same tile metrics as DecisionV2 so the two never read as different components.
Deny and Allow once only. Selected by neverRemember or the review shell, and it ignores any offered grants.
Replaces the decision bar only after AskWithdrawn(TIMED_OUT). Read-only body, single Dismiss, and the only state in which the sheet may be closed without a decision. An ordinary withdrawal or a session close removes the sheet outright and produces no TimeoutTerminal.
Approval only. The Sessions and Chat direction in A Master Core v1 and A Master Proofs v1 stays locked, including the approval entry points on those screens. Where those files disagree with this one about the approval sheet, this file wins.